//////////////////////////////////////////////////////////////////////////
//
// GAM203
// Direct X Manager
// DXMgr.h
// 
// Grant Johnson
// Qantm College
// 27/10/2010
//
//////////////////////////////////////////////////////////////////////////

#include "DXMgr.h"
#include "Renderer.h"

#define WIN32_LEAN_AND_MEAN


DXMgr* Singleton<DXMgr>::m_pInstance = NULL;

DXMgr::DXMgr()
: m_pD3D(NULL)
, m_pDevice(NULL)
, m_hParent(NULL)
{
	ZeroMemory(&m_presentParams, sizeof(m_presentParams));
}
DXMgr::~DXMgr()
{
	Shutdown();
}
bool DXMgr::Setup(HWND a_hWnd)
{
	m_hParent = a_hWnd;
	m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

	m_presentParams.Windowed = true;
	m_presentParams.SwapEffect = D3DSWAPEFFECT_FLIP;
	m_presentParams.hDeviceWindow = a_hWnd;
	m_presentParams.EnableAutoDepthStencil = true;
	m_presentParams.AutoDepthStencilFormat = D3DFMT_D24S8;
	m_presentParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

	//Create device
	HRESULT result = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, a_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_presentParams, &m_pDevice);
	if(FAILED(result))
	{
		//Failed to create device, undo init of d3d
		m_pD3D->Release();
		m_pD3D = NULL;
		return false;
	}

	return true;
}
void DXMgr::Resize()
{
	if(m_pDevice)
	{
		RECT rect;
		GetClientRect(m_hParent, &rect);
		//delete the renderer first
		//Renderer::Done();
		//Renderer::Init();
		if(m_pDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET)
		{
			m_presentParams.BackBufferWidth = rect.right;
			m_presentParams.BackBufferHeight = rect.bottom;

			HRESULT hr = m_pDevice->Reset(&m_presentParams);
			if(hr == D3DERR_INVALIDCALL)
			{
				return;
			}

			//Recreate the renderer
			if(FAILED(Renderer::GetInstance().Setup(m_pDevice, (float)rect.right, (float)rect.bottom)))
			{
				MessageBox(NULL, "Failed to Recreate the Renderer!", "Fail!", MB_OK | MB_ICONEXCLAMATION);
				return;
			}
		}
	}
}
void DXMgr::Shutdown()
{
	//Clean up
	if(m_pDevice)
	{
		m_pDevice->Release();
		m_pDevice = NULL;
	}

	if(m_pD3D)
	{
		m_pD3D->Release();
		m_pD3D = NULL;
	}
}
IDirect3D9* DXMgr::GetD3D() const
{
	return m_pD3D;
}
IDirect3DDevice9* DXMgr::GetDevice() const
{
	return m_pDevice;
}